﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Erau.ERBParser;

namespace Erau
{
	public delegate EraVar ErauFunction(List<EraVar> args);

	public partial class ErauEngine
	{
		private static ErauEngine instance = new ErauEngine();
		public static ErauEngine Instance { get { return instance; } }

		// 연결된 콘솔
		IErauConsole console = null;

		// 게임에서 사용되는 데이터가 들어가는 root Table
		EraTable gameData = new EraTable();
		public EraTable GameData { get { return gameData; } }

		// 스크립트 함수 목록.
		Dictionary<String, ErauFunction> functionTable = new Dictionary<string, ErauFunction>();
		public IDictionary<string, ErauFunction> FunctionTable { get { return functionTable; } }

		// 스크립트용 예약어(difine) 목록.
		IDictionary<string, string> scriptDefines = new Dictionary<string, string>();
		public IDictionary<string, string> ScriptDefines { get { return scriptDefines; } }

		public void RegisterFunction(string functionName, ErauFunction func)
		{
			if (functionTable.ContainsKey(functionName))
				throw new Exception("이미 존재하는 함수명임 -_-;");

			functionTable.Add(functionName, func);
		}

		public void SetConsole(IErauConsole console) { this.console = console; }

		public void Initialize()
		{
			// 연결된 콘솔이 없으면 예외처리하고 리턴해버림.
			if (console == null)
				throw new Exception("콘솔이 없어염");

			// 로딩 메세지 출력.
			console.Print("스크립트 파일 로딩/파싱중...\r\n");

			// 모든 ERB를 읽어서 파싱한다.
			LoadAllERB();

			// 스크립트에서 정의되어 있어야 하는 함수들이 존재하는지 체크.
			// 헌재는 SYSTEM_TITLE 하나뿐임.
			if (!functionTable.ContainsKey("SYSTEM_TITLE")) throw new Exception("SYSTEM_TITLE 엄씀");

			// SYSTEM_TITLE 스크립트 함수를 호출.
			functionTable["SYSTEM_TITLE"](null);
		}

		public void LoadAllERB()
		{
			ERBLoader loader = new ERBLoader();


			System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(@"\ERB");
			if (!di.Exists)
				throw new Exception("ERB폴더가 없음");

			foreach (System.IO.FileInfo f in di.GetFiles("*.erb", System.IO.SearchOption.AllDirectories))
			{
				loader.loadErb(f.DirectoryName, f.Name);
			}

		}
	}
}
